package com.hmdp.utils;

import com.hmdp.exception.WebException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

@Slf4j
@RequiredArgsConstructor
@Component
public class CacheClient {

    private final RedisTemplate<String, Object> redisTemplate;

    private final RedissonClient redissonClient;

    public void set(String key, Object value, Long timeout, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    public void setWithLogicalExpire(String key, Object value, Long timeout, TimeUnit timeUnit) {
        RedisData redisData = new RedisData();
        redisData.setData(value);
        redisData.setExpireTime(LocalDateTime.now().plusSeconds(timeUnit.toSeconds(timeout)));
        redisTemplate.opsForValue().set(key, redisData);
    }

    public <R, ID> R queryWithPassThrough(String keyPrefix, ID id, Function<ID, R> dbFallback, Long timeout, TimeUnit timeUnit) {
        String key = keyPrefix + id;
        Object o = redisTemplate.opsForValue().get(key);

        if (o != null) {
            if (o.equals("")) {
                throw new WebException("信息不存在...NULL");
            }
            return (R) o;
        }

        R r = dbFallback.apply(id);
        if (r == null) {
            redisTemplate.opsForValue().set(key, "", timeout, timeUnit);
            throw new WebException("信息不存在...DB");
        }

        this.set(key, r, timeout, timeUnit);
        return r;
    }
}
